package rs.udd.service.test.config;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import rs.udd.model.IModelMarker;
import rs.udd.repository.IRepositoryMarker;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackageClasses = { IRepositoryMarker.class })
@PropertySources({ @PropertySource("classpath:database.properties") })
public class UddTestPersistenceConfig {

	private static final String JDBC_DRIVER_CLASS_NAME = "jdbc.driverClassName";
	private static final String JDBC_URL = "jdbc.url";
	private static final String JDBC_USER = "jdbc.user";
	private static final String JDBC_PASS = "jdbc.pass";

	private static final String HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
	private static final String HIBERNATE_DIALECT = "hibernate.dialect";
	private static final String HIBERNATE_SHOW_SQL = "hibernate.show_sql";
	private static final String HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
	private static final String HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
	private static final String HIBERNATE_IMPORT_FILES = "hibernate.hbm2ddl.import_files";

	@Autowired
	private Environment env;

	@Bean
	public DataSource dataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName(env.getProperty(JDBC_DRIVER_CLASS_NAME));
		dataSource.setUrl(env.getProperty(JDBC_URL));
		dataSource.setUsername(env.getProperty(JDBC_USER));
		dataSource.setPassword(env.getProperty(JDBC_PASS));
		return dataSource;
	}

	private Properties jpaProperties() {
		Properties jpaProperties = new Properties();
		jpaProperties.setProperty(HIBERNATE_DIALECT, env.getProperty(HIBERNATE_DIALECT));
		jpaProperties.setProperty(HIBERNATE_HBM2DDL_AUTO, env.getProperty(HIBERNATE_HBM2DDL_AUTO));
		jpaProperties.setProperty(HIBERNATE_SHOW_SQL, env.getProperty(HIBERNATE_SHOW_SQL));
		jpaProperties.setProperty(HIBERNATE_FORMAT_SQL, env.getProperty(HIBERNATE_FORMAT_SQL));
		jpaProperties.setProperty(HIBERNATE_NAMING_STRATEGY, env.getProperty(HIBERNATE_NAMING_STRATEGY));
		jpaProperties.setProperty(HIBERNATE_IMPORT_FILES, env.getProperty(HIBERNATE_IMPORT_FILES));
		return jpaProperties;
	}

	@Bean
	public PlatformTransactionManager transactionManager() {
		EntityManagerFactory factory = entityManagerFactory().getObject();
		JpaTransactionManager txManager = new JpaTransactionManager(factory);
		return txManager;
	}

	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
		LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		vendorAdapter.setGenerateDdl(Boolean.TRUE);
		vendorAdapter.setShowSql(Boolean.FALSE);
		entityManagerFactory.setDataSource(dataSource());
		entityManagerFactory.setJpaVendorAdapter(vendorAdapter);
		entityManagerFactory.setPackagesToScan(IModelMarker.class.getPackage().getName());
		entityManagerFactory.setPersistenceProviderClass(HibernatePersistenceProvider.class);
		entityManagerFactory.setJpaProperties(jpaProperties());
		return entityManagerFactory;
	}

}
